#include "headers/ProcessMonitor.h"
#include <QDebug>
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>

ProcessMonitor::ProcessMonitor(QObject *parent)
    : QObject(parent)
    , m_timer(new QTimer(this))
    , m_allProcessTimer(new QTimer(this))
{
    connect(m_timer, &QTimer::timeout, this, &ProcessMonitor::checkProcesses);
    connect(m_allProcessTimer, &QTimer::timeout, this, &ProcessMonitor::refreshAllProcessInfo);
}

void ProcessMonitor::setGameProcessNames(const QStringList &processNames)
{
    m_gameProcessNames = processNames;
    qDebug() << "[ProcessMonitor] 已设置监控进程列表:" << m_gameProcessNames;
}

// 启动监控
void ProcessMonitor::startMonitor(int interval)
{
    m_timer->start(interval);
    m_allProcessTimer->start(1000);
    qDebug() << "[ProcessMonitor] 监控已启动，检测间隔:" << interval << "ms";
}

// 停止监控
void ProcessMonitor::stopMonitor()
{
    m_timer->stop();
    m_allProcessTimer->stop();
    m_lastProcessTimes.clear();
    qDebug() << "[ProcessMonitor] 监控已停止";
}

// 获取系统总运行时间
static qint64 getSystemTotalTime()
{
    FILETIME idleTime, kernelTime, userTime;
    if (GetSystemTimes(&idleTime, &kernelTime, &userTime)) {
        qint64 kernel = ((qint64)kernelTime.dwHighDateTime << 32) + kernelTime.dwLowDateTime;
        qint64 user = ((qint64)userTime.dwHighDateTime << 32) + userTime.dwLowDateTime;
        return kernel + user;
    }
    return 0;
}

// 获取单个进程的运行时间
static bool getProcessTime(DWORD pid, qint64 &kernelTime, qint64 &userTime)
{
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
    if (hProcess == NULL) {
        return false;
    }

    FILETIME creationTime, exitTime, kernelTimeFt, userTimeFt;
    if (GetProcessTimes(hProcess, &creationTime, &exitTime, &kernelTimeFt, &userTimeFt)) {
        kernelTime = ((qint64)kernelTimeFt.dwHighDateTime << 32) + kernelTimeFt.dwLowDateTime;
        userTime = ((qint64)userTimeFt.dwHighDateTime << 32) + userTimeFt.dwLowDateTime;
        CloseHandle(hProcess);
        return true;
    }

    CloseHandle(hProcess);
    return false;
}

// 刷新所有进程信息
void ProcessMonitor::refreshAllProcessInfo()
{
    QList<ProcessInfo> processList;
    qint64 currentSystemTime = getSystemTotalTime();
    PROCESSENTRY32W processEntry = {0};
    processEntry.dwSize = sizeof(PROCESSENTRY32W);
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        qDebug() << "[ProcessMonitor] 进程快照创建失败";
        return;
    }

    if (Process32FirstW(hSnapshot, &processEntry)) {
        do {
            DWORD pid = processEntry.th32ProcessID;
            QString processName = QString::fromWCharArray(processEntry.szExeFile);
            ProcessInfo info;
            info.processName = processName;
            info.cpuUsage = 0.0;

            qint64 currentKernelTime, currentUserTime;
            if (getProcessTime(pid, currentKernelTime, currentUserTime)) {
                if (m_lastProcessTimes.contains(pid)) {
                    ProcessTimeData lastData = m_lastProcessTimes[pid];
                    qint64 processTimeDiff = (currentKernelTime - lastData.kernelTime) + (currentUserTime - lastData.userTime);
                    qint64 systemTimeDiff = currentSystemTime - lastData.systemTime;

                    if (systemTimeDiff > 0 && processTimeDiff > 0) {
                        double cpu = (processTimeDiff * 100.0) / systemTimeDiff;
                        info.cpuUsage = qMin(100.0, cpu);
                    }
                }
                ProcessTimeData currentData;
                currentData.kernelTime = currentKernelTime;
                currentData.userTime = currentUserTime;
                currentData.systemTime = currentSystemTime;
                m_lastProcessTimes[pid] = currentData;
            }

            processList.append(info);

        } while (Process32NextW(hSnapshot, &processEntry));
    }

    CloseHandle(hSnapshot);
    m_processList = processList;
    emit allProcessUpdated(processList);
}

// 检测是否有游戏进程
void ProcessMonitor::checkProcesses()
{
    PROCESSENTRY32W processEntry = {0};
    processEntry.dwSize = sizeof(PROCESSENTRY32W);
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        qDebug() << "[ProcessMonitor] 违规检测：快照创建失败";
        return;
    }

    if (Process32FirstW(hSnapshot, &processEntry)) {
        do {
            QString processName = QString::fromWCharArray(processEntry.szExeFile);
            if (m_gameProcessNames.contains(processName, Qt::CaseInsensitive)) {
                emit gameProcessDetected(processName);
                qDebug() << "[ProcessMonitor] 检测到违规进程:" << processName;
                break;
            }
        } while (Process32NextW(hSnapshot, &processEntry));
    }

    CloseHandle(hSnapshot);
}

// 外部获取所有进程信息
QList<ProcessInfo> ProcessMonitor::getAllProcessWithCpuUsage()
{
    refreshAllProcessInfo();
    return m_processList;
}
